﻿using Microsoft.SharePoint.Client;
using System;
using System.Net;
using Microsoft.Online.SharePoint.TenantAdministration;

namespace Office365.SharePointOnline.Cmdlets
{
    [System.Management.Automation.Cmdlet(System.Management.Automation.VerbsCommon.Get, "TenantLog")]
    public class Get_TenantLog : System.Management.Automation.PSCmdlet
    {
        [System.Management.Automation.Parameter(Position = 0, Mandatory = true)]
        public string Url;

        [System.Management.Automation.Parameter(Position = 1, Mandatory = false)]
        public string User;

        [System.Management.Automation.Parameter(Position = 2, Mandatory = false)]
        public string Password;

        [System.Management.Automation.Parameter(Position = 3, Mandatory = false)]
        public string AuthenticationMethod;

        // use only if onpremise authentication
        [System.Management.Automation.Parameter(Position = 4, Mandatory = false)]
        public string Domain;

        protected override void ProcessRecord()
        {
            // check parameters
            ClientContext context = new ClientContext(Url);
            ICredentials credentials;
            Web web = context.Web;
            this.WriteVerbose("Logging on.");
            if (string.IsNullOrEmpty(Url))
            {
                this.WriteObject("Error: url is not set");
            }
            else
            {
                if (!string.IsNullOrEmpty(Password) && !string.IsNullOrEmpty(User))
                {
                    AuthenticationHelper authenticationHelper = new AuthenticationHelper() { AuthenticationMethod = AuthenticationMethod, Domain = Domain, Password = Password, User = User };
                    credentials = authenticationHelper.GetCredentials();
                    if (credentials != null)
                    {
                        context.Credentials = credentials as ICredentials;
                    }
                    else
                    {
                        throw new NullReferenceException("No credentials returned.");
                    }
                }
                else
                {
                    this.WriteVerbose("Reusing existing credentials");
                }

                this.WriteVerbose("Getting logs.");
                context.Load(web);
                context.ExecuteQuery();

                GetLogEntries(context, web);
            }
        }

        private void GetLogEntries(ClientContext context, Web web)
        {
            // see: http://www.vrdmn.com/2014/03/view-tenant-uls-logs-in-sharepoint.html
            // for now only seems to work on developer sites and admin sites

            var tenant = new Tenant(context);
            var tenantLog = new TenantLog(context);
            var dateTimeUTCNow = DateTime.UtcNow;

            //Get 1000 Rows of Tenant Log Entries starting from 365 days ago till now.
            var logEntries = tenantLog.GetEntries(dateTimeUTCNow.AddDays(-365), dateTimeUTCNow, 1000);

            // TODO: do linq query to get to stuff like getentriesbycorrelationid? 

            //Get 50 Rows of Tenant Log Entries of the specified CorrelationId starting from 5 days ago till now
            //var logEntries = tenantLog.GetEntriesByCorrelationId(dateTimeUTCNow.AddDays(-5), dateTimeUTCNow, 50, new Guid("ae2b1e34-12eb-4652-a0db-ce4ab916c74e"));

            //Get 50 Rows of Tenant Log Entries of the specified Source starting from 5 days ago till now.
            //var logEntries = tenantLog.GetEntriesBySource(dateTimeUTCNow.AddDays(-5), dateTimeUTCNow, 50, 1);

            //Get 50 Rows of Tenant Log Entries of the specified User starting from 5 days ago till now.
            //var logEntries = tenantLog.GetEntriesByUser(dateTimeUTCNow.AddDays(-5), dateTimeUTCNow, 50, "admin@yoursite.onmicrosoft.com");
            

            context.Load(logEntries);

            context.ExecuteQuery();

            foreach (TenantLogEntry logEntry in logEntries)
            {
                this.WriteObject(string.Format("Timestamp:{0} | Message:{1} | CorrelationId:{2} | Source:{3} | User:{4} | CategoryId:{5}",
                    logEntry.TimestampUtc, logEntry.Message, logEntry.CorrelationId, logEntry.Source, logEntry.User, logEntry.CategoryId));
            }
        }
    }
}
